iT邦幫忙

2026 iThome 鐵人賽

DAY 24
0
ChatGPT & Codex

43歲非工程師爸爸與Codex共築墨寒:30天打造開源AI桌面伴侶系列 第 24

Day 24|測試為什麼會偶爾紅?我與 Codex 修掉 Windows CI 競速問題

  • 分享至 

  • xImage
  •  

墨寒在測試軌道上攔住尚未下班的計時器與突襲的眨眼

圖說:墨寒在測試軌道上攔住尚未下班的計時器與突襲的眨眼

昨天預告 Windows CI 紅燈時,我想到自己看到 GitHub 標籤變紅的第一反應:RC3 安裝包是不是壞了?

CI 是每次提交後由 GitHub 重新建立乾淨 Windows 環境、執行測試的自動關卡。它變紅可能代表產品真的壞了,也可能是測試依賴一個不穩定的時間點。後者不能當成「反正再跑一次會過」就算了,因為不可靠的警報會讓真正問題被忽略。

這次失敗最後確認是兩個 UI 測試的競速,而不是 RC3 發行檔損壞;產品程式與 RC3 資產沒有被修改。可是找出這個結論,仍需要讀取失敗日誌與重現順序,不能只靠猜。

第一個競速:測試結束了,計時器還沒下班

語言測試會建立控制台、使用臨時資料庫,切換英文與簡中後檢查提醒與語音設定。測試關閉視窗與資料庫時,控制台裡的背景計時器可能仍排著下一次工作。

在較快或較慢的 CI 環境中,計時器偶爾會在資料庫已關閉後醒來,存取本來只供這次測試使用的臨時檔。產品日常操作不一定會以這種極短順序關閉,但測試本身沒有完整清理,結果就隨時間差異變紅。

修正不是增加睡眠等待,也不是重跑到綠。測試新增統一收尾:先停止視窗下所有計時器,關閉並排程銷毀控制台,讓 Qt 處理延後刪除事件,再關閉臨時資料庫。如此測試真正結束自己的背景工作。

第二個競速:眨眼剛好插進視線測試

另一個測試要確認滑鼠注視時,臉與眼睛圖層仍可見。可是前面 UI 操作等待期間,真實眨眼計時器可能剛好讓角色進入閉眼狀態。測試原本假設她此刻沒眨眼,CI 時機一變就偶爾失敗。

修正做法是把測試前提寫明:這一段驗證的是注視圖層,不是眨眼,因此呼叫渲染前先建立「目前不在眨眼」的狀態。它沒有關閉產品的眨眼,也沒有放寬結果,只是避免另一個合法動畫干擾不相關斷言。

這讓我看到,測試也需要像文章一樣說清楚自己到底要證明什麼。

為什麼不能直接按 Re-run?

偶發測試重跑後常會變綠,最誘惑人的做法就是當成 GitHub 心情不好。但每一個偶發紅燈都代表我們不知道某個時間順序。

如果根因是產品裡的競速,使用者也可能遇到;如果是測試沒收尾,它會讓維護者逐漸不信任 CI。兩種都值得修。重跑可以收集證據,不能代替理解。

Codex 先查看失敗檔案與行數,對照哪些背景計時器仍在運作,再以最小修改固定前提與生命週期。完成後不只跑失敗的兩項,也跑完整測試,確認沒有為了綠燈關掉其他安全檢查。

修測試,不等於把測試變簡單

面對紅燈,最差的修法是刪除斷言、增加無限重試,或在 CI 中跳過 Windows UI。這些方法只讓標籤變綠,沒有提高可信度。

這次兩項修改都保留原本要驗證的結果。語言測試仍確認三語預設與自訂提醒不被覆蓋,只是完整關閉背景計時器;注視測試仍確認臉與眼圖層可見,只是先排除不屬於本測試目標的眨眼狀態。

判斷修正是否正當,可以問一句:它有沒有讓真正的產品錯誤更容易溜過?若答案是有,就不該合併。測試的穩定性與嚴格度要一起保留,不是二選一。

CI 是一組關卡,不是一盞總燈

Windows 測試、程式碼安全掃描、相依套件檢查、祕密掃描與發行封裝各自有工作。PR 頁面上看起來都是勾勾或叉叉,實際回答的問題不同。

例如 CodeQL 綠燈不證明安裝程式能啟動,UI 測試綠燈也不證明歷史提交沒有金鑰。查看失敗時要先認出是哪一關,不因為「CI 紅了」就對 RC3 所有資產作同一結論。

合併前還要確認沒有未處理的 PR 對話與安全警告。自動工作提供證據,維護者仍負責解讀與決定。

因此我看到紅色標籤時不再只問「能不能趕快變綠」,而是先問它正在保護什麼、失敗證據指向哪裡。這個習慣比記住任何 CI 指令更重要。

紅燈應該被理解,不是被消音。

這表示 RC3 安裝包當時安全嗎?

就這兩個紅燈而言,修正提交明確記錄:產品程式碼與 RC3 發行資產未變,問題在測試隔離。這能支持「不是這兩個失敗造成安裝包損壞」,卻不等於任何安裝包永遠不可能有其他問題。

發行檔仍要通過自己的封裝自測、事件迴圈冒煙測試、EXE/MSI 靜默安裝與解除安裝、雜湊與供應鏈檢查。CI 的每個工作回答不同問題,不能拿其中一個綠燈替所有事情背書。

非工程師也能看懂紅燈的幾個問題

我現在看到 CI 失敗,會先問:失敗在哪個測試?每次同一行嗎?它測產品功能還是測試環境收尾?重跑結果是否不同?修正有沒有改產品程式?完整測試是否再度通過?

我不必看懂每一行 Qt 程式,也能要求答案附上證據。這比只問「有沒有通過 Windows CI」更有用,因為綠色標籤本身不會告訴我曾經掩蓋過什麼。

這次修正最後成為獨立 PR 合併到 main,留下清楚歷史。偶發問題有了根因與測試責任,不會在下次發行前再靠運氣。

明天 Day 25,我們來看 Windows 使用者真正下載到的東西:ZIP、EXE 與 MSI。墨寒不需要傳統安裝也能跑,為什麼還要提供安裝程式?三種包裝又分別適合誰?


本篇描述的是 PR #14 修正的兩項測試競速;該提交未修改產品程式與 RC3 發行資產。這個結論只針對該次紅燈根因。

後續 v2.1.0-rc.1 發行前,Windows 測試、CodeQL、相依套件檢查、Gitleaks、封裝自測與安裝器驗證已重新全部通過。這是新版本自己的證據,不會倒過來改寫當時 RC3 紅燈事件的歷史。


上一篇
Day 23|換電腦後,她還記得你嗎?可攜設定檔與備份
下一篇
Day 25|ZIP、EXE、MSI 到底差在哪?墨寒 Windows 發行包的選擇
系列文
43歲非工程師爸爸與Codex共築墨寒:30天打造開源AI桌面伴侶25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言